#requires -version 2.0 
function Get-NaIGroup {
	<#
	.Synopsis
  	 	Get information for initiator group(s).
	.Description
   		Get information for initiator group(s).
	.Parameter Name
   		Name of initiator group. If specified, only information for that group is returned. If not
 		specified, information for all inititor groups are returned. 
	.Parameter Server
   		NaServer to query
	.Example
		PS > Get-NaIGroup
	.Outputs
    	NetApp.SDK.NaIGroup[]
    .Link
    	Get-NaIGroup
    	Set-NaIGroup
    	Rename-NaIGroup
    	Remove-NaIGroup	
    #> 
	[CmdletBinding(SupportsShouldProcess=$FALSE,SupportsTransactions=$False,ConfirmImpact="None",DefaultParameterSetName="")]
	param ( 
        [Parameter(position=0,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Name of initiator group. If specified, only information for that group is returned.")]
		[Alias("IGroup")]
		[string]
		$Name,
	
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer] 
		$server = (Get-NaServer)
	)
	Process {
		$request = New-Object Netapp.Manage.NaElement -ArgumentList @("igroup-list-info")
		if ($Name){
			$request.AddNewChild("initiator-group-name",$name)
		}
		try {
			$result = ([xml]$server.InvokeElem($request)).results
		}
		catch [NetApp.Manage.NaApiFailedException]{
			Write-Warning $_.Exception.GetBaseException().message
			$result = $null
			continue;
		}
		if ($?){
			$result."initiator-groups"."initiator-group-info" | % {
				if ($_."initiator-group-name"){
					return New-Object NetApp.SDK.NaIGroup -ArgumentList @(
						$_."initiator-group-name",
						$_."initiator-group-os-type",
						$_."initiator-group-type",
						[array]($_.initiators."initiator-info"|%{$_."initiator-name"}),
						(ConvertFrom-NaBool $_."initiator-group-alua-enabled"),
						(ConvertFrom-NaBool $_."initiator-group-throttle-borrow"),
						(ConvertFrom-NaBool $_."initiator-group-vsa-enabled"),
						$_."initiator-group-throttle-reserve",
						$_."lun-id",
						(ConvertFrom-NaBool $_."initiator-group-use-partner"),
						$_."initiator-group-portset-name"
					)
				}
			}
		}
	}
}
function Set-NaIGroup {
	<#
	.Synopsis
   		Sets an attribute for an initiator group.
	.Description
  		Sets an attribute for an initiator group.
	.Parameter Name
   		Name of initiator group. If specified, only information for that group is returned. If not
 		specified, information for all inititor groups are returned. 
 	.Parameter ThrottleReserve
   		Set the reserved for this initiator group's exclusive usage. 
	.Parameter ThrorrleBarrow
   		If set to TRUE then allow the igroups throttle reserve to be exceeded if the igroup attempts
 		to use more than it has reserved. 
	Parameter AULA
   		If set to TRUE then this initiator group has ALUA (Asymmetric Logical Unit Access) features
 		enabled for luns mapped to this initiator group.  
	.Parameter OSType
   		OS type of the initiator group.
		
 		Possible values: aix, hpux, linux, solaris, windows, netware, unknown, vmware, openvms 
	.Parameter FORCE
  		Forcibly set the attribute, disabling conflict checks with the cluster partner where and 
 		when applicable. if not specified all conflict checks are performed.
	.Parameter UnBindPortSet
   		Name of portset to unbind from the iGroup. 
	.Parameter BindPortSet
   		Name of portset to bind the iGroup to. 
	.Parameter Server
	   	NaServer to query
	.Example
		# Set the OSType of the IGroup vmware
		PS > Set-NaIGroup -Name vmware -OSType vmware
	.Outputs
    	NetApp.SDK.NaIGroup[]
    .Link
    	Get-NaIGroup
    	Rename-NaIGroup
    	Remove-NaIGroup
    	New-NaIGroup	
   #> 
	[CmdletBinding(SupportsShouldProcess=$true,SupportsTransactions=$False,ConfirmImpact="low",DefaultParameterSetName="OSType")]
	param ( 
		[Parameter(mandatory=$TRUE,Position=0,ParameterSetName="throttlereserve",ValueFromPipelinebypropertyname=$TRUE,HelpMessage="Name of initiator group")]
		[Parameter(mandatory=$TRUE,Position=0,ParameterSetName="throttlebarrow",ValueFromPipelinebypropertyname=$TRUE,HelpMessage="Name of initiator group")]
		[Parameter(mandatory=$TRUE,Position=0,ParameterSetName="aula",ValueFromPipelinebypropertyname=$TRUE,HelpMessage="Name of initiator group")]
		[Parameter(mandatory=$TRUE,Position=0,ParameterSetName="OSType",ValueFromPipelinebypropertyname=$TRUE,HelpMessage="Name of initiator group")]
		[Parameter(mandatory=$TRUE,Position=0,ParameterSetName="unbindportset",ValueFromPipelinebypropertyname=$TRUE,HelpMessage="Name of initiator group")]
		[Parameter(mandatory=$TRUE,Position=0,ParameterSetName="bindportset",ValueFromPipelinebypropertyname=$TRUE,HelpMessage="Name of initiator group")]
		[Alias("IGroup")]
		[string]
		$Name,
	
		[Parameter(mandatory=$TRUE,ParameterSetName="throttlereserve",HelpMessage="Set the Throttle Reserve of the initiator group, valid values are 0-99")]
		[ValidateRange(0,99)]
		[int]
		$ThrottleReserve,
	
		[Parameter(mandatory=$TRUE,ParameterSetName="throttlebarrow",HelpMessage="enabled/disable Throttle Barrowing on the initiator group.")]
		[bool]
		$ThrottleBarrow,
	
		[Parameter(mandatory=$TRUE,ParameterSetName="aula",HelpMessage="enabled/disable AULA (Asymmetric Logical Unit Access) on the initiator group.")]
		[bool]
		$AULA,
	
		[Parameter(mandatory=$TRUE,ParameterSetName="OSType",HelpMessage="OS type of the initiators within the group.")]
		[ValidateSet("default", "solaris", "windows", "hpux", "aix", "linux", "netware", "vmware", "openvms")]
		[string]
		$OSType,
	
		[Parameter(ParameterSetName="OSType")]
		[switch]
		$Force,
	
		[Parameter(mandatory=$TRUE,ParameterSetName="unbindportset")]
		[switch]
		$UnBindPortSet,
	
		[Parameter(mandatory=$TRUE,ParameterSetName="bindportset")]
		[string]
		$BindPortSet,
	
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer] 
		$server = (Get-NaServer)
	)
	Process {
		switch ($PSCmdlet.ParameterSetName)
        {
			"bindportset" 
			{
				$request = New-Object Netapp.Manage.NaElement -ArgumentList @("igroup-bind-portset")
				$request.AddNewChild("initiator-group-name",$Name)
				$request.AddNewChild("portset-name",$BindPortSet)
				$msg = "Binding $BindPortSet portset" 
			}
			"unbindportset" 
			{
				$request = New-Object Netapp.Manage.NaElement -ArgumentList @("igroup-unbind-portset")
				$request.AddNewChild("initiator-group-name",$Name)
				$msg = "UnBinding portset" 
			}
			"throttlereserve"
			{
				$request = New-Object Netapp.Manage.NaElement -ArgumentList @("igroup-set-attribute")
				$request.AddNewChild("initiator-group-name",$Name)
				$request.AddNewChild("attribute","throttle_reserve")
				$request.AddNewChild("value",$ThrottleReserve)
				$msg = "Setting Throttle Reserve to $ThrottleReserve "
			}
			"throttlebarrow" 
			{
				$request = New-Object Netapp.Manage.NaElement -ArgumentList @("igroup-set-attribute")
				$request.AddNewChild("initiator-group-name",$Name)
				$request.AddNewChild("attribute","throttle_borrow")
				$request.AddNewChild("value",$ThrottleBarrow)
				$msg = "Setting Throttle Barrow to $ThrottleBarrow "
			}
			"aula"
			{
				$request = New-Object Netapp.Manage.NaElement -ArgumentList @("igroup-set-attribute")
				$request.AddNewChild("initiator-group-name",$Name)
				$request.AddNewChild("attribute","alua")
				$request.AddNewChild("value",$AULA)
				$msg = "Setting AULA to $AULA "
			}
			"OSType"
			{
				$request = New-Object Netapp.Manage.NaElement -ArgumentList @("igroup-set-attribute")
				$request.AddNewChild("initiator-group-name",$Name)
				$request.AddNewChild("attribute","os-type")
				$request.AddNewChild("value",$OSType)
				$msg = "Setting OS-TYPE to $OSType "
				if ($force) {
					$request.AddNewChild("force",$TRUE)
				}
			}
		}
		if ($pscmdlet.ShouldProcess($Name, $msg)) {
			try {
				$server.InvokeElem($request)|out-null
			}
			catch [NetApp.Manage.NaApiFailedException]{
				Write-Warning $_.Exception.GetBaseException().message
				continue;
       		}
			if ($?){return Get-NaIGroup -Name $name -server $server}
		} 
	}
}
Function New-NaIGroup {
	<#
	.Synopsis
   		Creates a new initiator group.
	.Description
   		Creates a new initiator group.  See the Add-NaInitiator cmdlet for adding initiators to
 		the newly created IGroup.
	.Parameter Name
   		Name of initiator group. 
	.Parameter Type
   		Type of the initiator group, currently only "iscsi" and "fcp" are supported. 
	.Parameter OSType
   		OS type of the initiator group.
		
 		Possible values: aix, hpux, linux, solaris, windows, netware, unknown, vmware, openvms 
	.Parameter PortSet
   		Name of a current portset to bind to the newly created igroup.
	.Parameter Server
   		NaServer to query
	.Example
		# Create an empty igroup named VMData.
   		New-NaIGroup -name VMData -Type iscsi -OSType vmware
	.Outputs
    	NetApp.SDK.NaIGroup[]
    .Link
    	Get-NaIGroup
    	Set-NaIGroup
    	Rename-NaIGroup
    	Remove-NaIGroup	
    #> 
	[CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="low",DefaultParameterSetName="")]
	param ( 
		[Parameter(mandatory=$TRUE,Position=0,ValueFromPipelinebypropertyname=$TRUE,HelpMessage="Name of initiator group")]
		[Alias("IGroup")]
		[string]
		$Name,
	
		[Parameter(mandatory=$TRUE,Position=1,ValueFromPipelinebypropertyname=$TRUE,HelpMessage="Type of the initiator group, currently only 'iscsi' and 'fcp' are supported.")]
		[ValidateSet("iscsi","fcp")]
		[string]
		$Type,
	
		[Parameter(mandatory=$TRUE,Position=2,ValueFromPipelinebypropertyname=$TRUE,HelpMessage="OS type of the initiators within the group.")]
		[ValidateSet("solaris", "windows", "hpux", "aix", "linux", "netware", "vmware", "openvms")]
		[string]
		$OSType,
	
		[Parameter(ValueFromPipelinebypropertyname=$TRUE,HelpMessage="Name of a current portset to bind to the newly created igroup.")]
		[string]
		$PortSet,
	
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer] 
		$server = (Get-NaServer)
	)
	Process {
		$request = New-Object Netapp.Manage.NaElement -ArgumentList @("igroup-create")
		$request.AddNewChild("initiator-group-name",$Name)
		$request.AddNewChild("initiator-group-type",$Type)
		$request.AddNewChild("os-type",$OSType)
		if ($PortSet) {
			$request.AddNewChild("bind-portset",$PortSet)
		}
		if ($pscmdlet.ShouldProcess($Server.server, "Create IGroup $Name")) {
			try {
				$server.InvokeElem($request)|out-null
			}
			catch [NetApp.Manage.NaApiFailedException]{
				Write-Warning $_.Exception.GetBaseException().message
				$result = $null
				continue;
			}
			if ($?){return Get-NaIGroup -Name $name -server $server}
		} 
	}
}
Function Remove-NaIGroup {
	<#
	.Synopsis
   		Destroys an existing initiator group.
	.Description
   		Destroys an existing initiator group. By default a group cannot be destroyed
   		if there are existing lun maps defined for that group. This behaviour can be
   		overridden with the use of force option.  -Force will destroy the initiator 
   		group and any associated lun maps.
	.Parameter Name
   		Name of initiator group. 
	.Parameter Force
   		Forcibly destroy the initiator group, even if there are existing lun maps. 
   		Best practice is to attempt to unmap all the luns associated with a group 
   		before destroying it.
	.Parameter Server
   		NaServer to query
	.Example
   		# Remove IGroup vmdata from the filer
   		PS > Remove-NaIGroup -name vmdata
	.Example
	 	# Remove all unused Igroups from the system.
	 	PS > Get-NaIGroup | ? {$_.Initiators -eq $null} | Remove-NaIGroup -whatif
    .Link
    	Get-NaIGroup
    	Set-NaIGroup
    	Rename-NaIGroup
   	#> 
	[CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="low",DefaultParameterSetName="")]
	param ( 
		[Parameter(mandatory=$TRUE,Position=0,ValueFromPipelinebypropertyname=$TRUE,HelpMessage="Name of initiator group.")]
		[Alias("IGroup")]
		[string]
		$Name,
	
		[Parameter()]
		[switch]
		$Force,
	
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer] 
		$server = (Get-NaServer)
	)
	Process {
		$request = New-Object Netapp.Manage.NaElement -ArgumentList @("igroup-destroy")
		$request.AddNewChild("initiator-group-name",$Name)
		if ($force) {
			$request.AddNewChild("force",$TRUE)
		}
		if ($pscmdlet.ShouldProcess($server.server, "Destroying $Name")) {
			try {
				$server.InvokeElem($request)|out-null
			}
			catch [NetApp.Manage.NaApiFailedException]{
				Write-Warning $_.Exception.GetBaseException().message
				continue;
			}
		} 
	}
}
Function Rename-NaIGroup {
	<#
	.Synopsis
   		Rename an existing initiator group. 
	.Description
	   	rename an existing initiator group. The rename operation is non-disruptive.
	.Parameter Name
   		New name to be given to initiator group. 
	.Parameter Name
   		Name of initiator group to be renamed. 
	.Parameter Server
   		NaServer to query
	.Example
   		# Rename IGroup vmdata to vmdata1
   		ps > Rename-NaIGroup -Name vmdata -NewName vmdata1
	.Outputs
    	NetApp.SDK.NaIGroup[]
    .Link
    	Get-NaIGroup
    	Set-NaIGroup
    	New-NaIGroup
    	Remove-NaIGroup	
   	#> 
	[CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="low",DefaultParameterSetName="")]
	param ( 
		[Parameter(mandatory=$TRUE,Position=0,ValueFromPipelinebypropertyname=$TRUE,HelpMessage="Name of initiator group to be renamed.")]
		[Alias("IGroup")]
		[string]
		$Name,
		
		[Parameter(mandatory=$TRUE,Position=1,HelpMessage="New name to be given to initiator group.")]
		[string]
		$NewName,
	
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer] 
		$server = (Get-NaServer)
	)
	Process {
		$request = New-Object Netapp.Manage.NaElement -ArgumentList @("igroup-rename")
		$request.AddNewChild("initiator-group-name",$Name)
		$request.AddNewChild("initiator-group-new-name",$NewName)
		if ($pscmdlet.ShouldProcess($server.server, "Renaming $name to $NewName")) {
			try {
				$server.InvokeElem($request)|out-null
			}
			catch [NetApp.Manage.NaApiFailedException]{
				Write-Warning $_.Exception.GetBaseException().message
				$result = $null
				continue;
			}
			if ($?){return Get-NaIGroup -Name $newname -server $server}
		} 
	}
}

Function Add-NaInitiator {
	<#
	.Synopsis
   		Adds initiator to an existing initiator group.
	.Description
   		Adds initiator to an existing initiator group.
	.Parameter Name
   		WWPN or Alias of Initiator to add. 
	.Parameter IGroup
   		Name of initiator group. 
	.Parameter Force
   		Forcibly add the initiator, disabling mapping and type conflict checks 
   		with the cluster partner. If not specified all conflict checks are performed. 
	.Parameter Server
   		NaServer to query
	.Example
		# Add the iqn.1998-01.com.vmware:esx01 initiator to the vmware IGroup
		PS > Get-NaIGroup vmware | Add-NaInitiator -Name iqn.1998-01.com.vmware:esx01
	.Outputs
    	NetApp.SDK.NaIGroup[]
    .Link
    	Get-NaIGroup
    	Remove-NaInitiator
   	#> 
	[CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="low",DefaultParameterSetName="")]
	param ( 
		[Parameter(mandatory=$TRUE,ValueFromPipelinebypropertyname=$TRUE,Position=0,HelpMessage="WWPN or Alias of Initiator to add.")]
		[alias("Initiator")]
		[string]
		$Name,
	
		[Parameter(mandatory=$TRUE,Position=1,ValueFromPipelinebypropertyname=$TRUE,HelpMessage="Name of initiator group.")]
		[string]
		$IGroup,
	
		[Parameter()]
		[switch]
		$force,
	
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer] 
		$server = (Get-NaServer)
	)
	Process {
		$request = New-Object Netapp.Manage.NaElement -ArgumentList @("igroup-add")
		$request.AddNewChild("initiator-group-name",$IGroup)
		$request.AddNewChild("initiator",$Name)
		if ($Force) {
			$request.AddNewChild("force",$TRUE)
		}
		if ($pscmdlet.ShouldProcess($Server.server, "Adding $Name to $IGroup ")) {
			try {
				$server.InvokeElem($request)|out-null
			}
			catch [NetApp.Manage.NaApiFailedException]{
				Write-Warning $_.Exception.GetBaseException().message
				$result = $null
				continue;
       		}
			if ($?){return Get-NaIGroup -Name $IGroup -server $server}
		} 
	}
}
Function Remove-NaInitiator {
	<#
	.Synopsis
   		Removes an initiator from an existing initiator group.
	.Description
   		Removes an initiator from an existing initiator group.
	.Parameter Name
   		WWPN or Alias of Initiator to remove. 
	.Parameter IGroup
   		Name of initiator group. 
	.Parameter Force
   		Forcibly remove the initiator, disabling mapping and type conflict checks 
   		with the cluster partner. If not specified all conflict checks are performed. 
	.Parameter Server
   		NaServer to query
	.Example
		# remove the iqn.1998-01.com.vmware:esx01 initiator from the vmware IGroup
		PS > Get-NaIGroup vmware | Remove-NaInitiator -Name iqn.1998-01.com.vmware:esx01
	.Outputs
    	NetApp.SDK.NaIGroup[]
    .Link
    	Get-NaIGroup
    	Add-NaInitiator
   #> 
	[CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="low",DefaultParameterSetName="")]
	param ( 
		[Parameter(mandatory=$TRUE,ValueFromPipeline=$TRUE,Position=0,HelpMessage="WWPN or Alias of Initiator to remove.")]
		[alias("Initiator")]
		[string]
		$Name,
	
		[Parameter(mandatory=$TRUE,Position=1,ValueFromPipelinebypropertyname=$TRUE,HelpMessage="Name of initiator group.")]
		[string]
		$IGroup,
	
		[Parameter()]
		[switch]
		$force,
	
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer] 
		$server = (Get-NaServer)
	)
	Process {
		$request = New-Object Netapp.Manage.NaElement -ArgumentList @("igroup-remove")
		$request.AddNewChild("initiator-group-name",$IGroup)
		$request.AddNewChild("initiator",$Name)
		if ($Force) {
			$request.AddNewChild("force",$TRUE)
		}
		if ($pscmdlet.ShouldProcess($Server.server, "Removing $Name from $Igroup")) {
			try {
				$server.InvokeElem($request)|out-null
			}
			catch [NetApp.Manage.NaApiFailedException]{
				Write-Warning $_.Exception.GetBaseException().message
				$result = $null
				continue;
       		}
			if ($?){
				return Get-NaIGroup -Name $IGroup -server $server
			}
		} 
	}
}

Function Get-NaPortSet {
	<#
	.Synopsis
		Get information for port set(s).
	.Description
		Get information for port set(s).
	.Parameter Name
		Name of port set. If specified, only information for that set is returned. 
		If not specified, information for all port sets are returned. 
	.Parameter Server
   		NaServer to query
	.Example
		PS > Get-NaPortSet
	.Outputs
    	NetApp.SDK.NaPortSet[]
    .Link
    	Get-NaPortSet
    	New-NaPortSet
    	Remove-NaPortSet
    	Get-NaIGroup
   	#> 
	[CmdletBinding(SupportsShouldProcess=$False,SupportsTransactions=$False,ConfirmImpact="low",DefaultParameterSetName="")]
	param ( 
		[Parameter(Position=0,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Name of port set. If specified, only information for that set is returned.")]
		[Alias("PortSet")]
		[string]
		$Name,
	
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer]
		$server = (Get-NaServer)
	)
	Process {
		$request = New-Object Netapp.Manage.NaElement -ArgumentList @("portset-list-info")
		if ($Name) {
			$request.AddNewChild("portset-name",$Name)
		}
		try {
			$result = ([xml]$server.InvokeElem($request)).results
		}
		catch [NetApp.Manage.NaApiFailedException]{
			Write-Warning $_.Exception.GetBaseException().message
			$result = $null
			return $result
			continue;
   		}
		if ($?){
			$Ports = New-Object Hashtable
			$result."portset-sets"."portset-info" |% {
				$_."portset-port-info"."portset-ports" | % {
					[array]$initiators = $_."initiator-group-info"."portset-initiator-groups"| % {$_."initiator-group-name"}
					$Ports.Add($_."port-name",$initiators)
				}
				return New-Object NetApp.SDK.NaPortSet -ArgumentList @(
					$_."portset-name",
					$Ports,
					$_."portset-type",
					$_."portset-port-total"
				)
			}
		}
	}
}
Function New-NaPortSet {
	<#
	.Synopsis
		Create a port set
	.Description
		Create a port set
	.Parameter Name
		Name of the port set to create. 
	.Parameter Type
		Type of the port set ("fcp" or "iscsi"). Currently only "fcp" is supported. 
	.Parameter Server
   		NaServer to query
	.Example
		# Create an new iSCSI PortSet named PS1
   		New-NaPortSet -name PS1 -Type iscsi
	.Outputs
    	NetApp.SDK.NaPortSet[]
    .Link
    	Get-NaPortSet
    	Remove-NaPortSet
    	Get-NaIGroup
   	#> 
	[CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="low",DefaultParameterSetName="")]
	param ( 
		[Parameter(Mandatory=$TRUE,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Name of the port set to create.")]
		[Alias("Portset")]
		[string]
		$Name,
	
		[Parameter(Mandatory=$TRUE,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Type of the port set ('fcp' or 'iscsi').")]
		[ValidateSet("fcp", "iscsi")]
		[string]
		$Type,
	
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer] 
		$server = (Get-NaServer)
	)
	Process {
		$request = New-Object Netapp.Manage.NaElement -ArgumentList @("portset-create")
		$request.AddNewChild("portset-name",$Name)
		$request.AddNewChild("portset-type",$Type)
		if ($pscmdlet.ShouldProcess($server.server, "Creating $Name")) {
			try {
				$server.InvokeElem($request)|out-null
			}
			catch [NetApp.Manage.NaApiFailedException]{
				Write-Warning $_.Exception.GetBaseException().message
				$result = $null
				continue;
       		}
			if ($?){
				return Get-NaPortSet -Name $Name -server $Server
			}
		} 
	}
}
Function Remove-NaPortSet {
	<#
	.Synopsis
		Destroys an existing port set.
	.Description
		Destroys an existing port set. By default a set cannot be destroyed if
		there are existing igroup associated with that pset.
	.Parameter Name
		Name of the port set to destroy. 
	.Parameter Force
		Forcibly destroy the portset, even if there are existing igroup bindings. 
		Best practice is to attempt to unbind all the associated igroups before 
		destroying it. 
	.Parameter Server
   		NaServer to query
	.Example
		# Remove the PO1 portset
		PS > Remove-NaPortSet -Name PO1
	.Outputs
    	NetApp.SDK.NaPortSet[]
    .Link
    	Get-NaPortSet
    	Remove-NaPortSet
    	Get-NaIGroup
   	#> 
	[CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="low",DefaultParameterSetName="")]
	param ( 
		[Parameter(Mandatory=$TRUE,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Name of the port set to Destroy.")]
		[Alias("Portset")]
		[string]
		$Name,
	
		[Parameter()]
		[switch]
		$force,
	
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer] 
		$server = (Get-NaServer)
	)
	Process {
		$request = New-Object Netapp.Manage.NaElement -ArgumentList @("portset-destroy")
		$request.AddNewChild("portset-name",$Name)
		if ($Force) {
			$request.AddNewChild("force",$TRUE)
		}
		if ($pscmdlet.ShouldProcess($Server.server, "Destroy portset $Name")) {
			try {
				$server.InvokeElem($request)|out-null
			}
			catch [NetApp.Manage.NaApiFailedException]{
				Write-Warning $_.Exception.GetBaseException().message
				$result = $null
				continue;
			}
		} 
	}
}

Function Add-NaPort {
	<#
	.Synopsis
   		Add a port to an existing port set
	.Description
   		Add a port to an existing port set
	.Parameter Name
   		This is the name of the port that is to be added to the portset. It can 
   		be input in two styles. The filername:slotletter format will add the port 
   		from a specific filer. For example: "buxton:4a" The slotletter format will 
   		add the port from both the local and partner filers. For example: "4a" 
	.Parameter PortSet
   		Name of the port set. 
	.Parameter Server
   		NaServer to query
	.Example
		PS > Add-NaPort -Name 4a -PortSet PO1
	.Outputs
    	NetApp.SDK.NaPortSet[]
    .Link
    	Get-NaPortSet
    	Remove-NaPort
   	#> 
	[CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="low",DefaultParameterSetName="")]
	param ( 
		[Parameter(Mandatory=$TRUE,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="This is the name of the port that is to be added to the portset.")]
		[Alias("port")]
		[string]
		$Name,
		
		[Parameter(Mandatory=$TRUE,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Name of port set.")]
		[string]
		$PortSet,
	
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer] 
		$server = (Get-NaServer)
	)
	Process {
		$request = New-Object Netapp.Manage.NaElement -ArgumentList @("portset-create")
		$request.AddNewChild("portset-name",$PortSet)
		$request.AddNewChild("portset-port-name",$Name)
		if ($pscmdlet.ShouldProcess($server.server, "Adding $Name to $PortSet")) {
			try {
				$server.InvokeElem($request)|out-null
			}
			catch [NetApp.Manage.NaApiFailedException]{
				Write-Warning $_.Exception.GetBaseException().message
				$result = $null
				continue;
			}
			if ($?){return Get-NaPortSet -Name $PortSet -Server $Server}
		} 
	}
}

Function Remove-NaPort {
	<#
	.Synopsis
   		Removes a port from a port set.
	.Description
   		Removes a port from a port set.
	.Parameter Name
   		This is the name of the port that is to be removed from the portset. It 
   		can be input in two styles. The filername:slotletter format will remove 
   		the port from a specific filer. For example: "buxton:4a" The slotletter 
   		format will remove the port from both the local and partner filers. 
   		For example: "4a" 
	.Parameter PortSet
   		Name of the port set.  
	.Parameter Server
   		NaServer to query
	.Example
		PS > Remove-NaPort -Name 4a -PortSet PO1
	.Outputs
    	NetApp.SDK.NaPortSet[]
    .Link
    	Get-NaPortSet
    	Remove-NaPort
   	#> 
	[CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="low",DefaultParameterSetName="")]
	param ( 
		[Parameter(Mandatory=$TRUE,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="This is the name of the port that is to be removed from the portset.")]
		[Alias("port")]
		[string]
		$Name,
	
		[Parameter(Mandatory=$TRUE,ValueFromPipelineByPropertyName=$TRUE,HelpMessage="Name of the port set to create.")]
		[string]
		$PortSet,
	
		[Parameter(HelpMessage="NaServer to query")]
		[NetApp.SDK.NaServer] 
		$server = (Get-NaServer)
	)
	Process {
		$request = New-Object Netapp.Manage.NaElement -ArgumentList @("portset-remove")
		$request.AddNewChild("portset-name",$PortSet)
		$request.AddNewChild("portset-port-name",$name)
		if ($pscmdlet.ShouldProcess($Server.server, "Removing $Name from $PortSet")) {
			try {
				$server.InvokeElem($request)|out-null
			}
			catch [NetApp.Manage.NaApiFailedException]{
				Write-Warning $_.Exception.GetBaseException().message
				$result = $null
				continue;
			}
			if ($?){return Get-NaPortSet -Name $PortSet -Server $Server}
		} 
	}
}
